using System;
using System.Collections.Generic;
using System.Text;
using xWinFormsLib;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Timers;

namespace QuizArena
{
    class QuizForm : Form
    {
        private int tempoRestante;

        private bool cronometroFuncionando;

        private Random random = new Random();
        float alturaTexto;

        protected String textoAlternativaCerta;

        public const String TITULO = "QUIZ";
        public const String TEMPO_RESTANTE = "Tempo restante: ";

        private Timer cronometro;

        private float posicaoAlternativas = 60;

        private Label labelTempoRestante;
        private Label labelEnunciado;

        private TextButton botaoAlternativaA;
        private TextButton botaoAlternativaB;
        private TextButton botaoAlternativaC;
        private TextButton botaoAlternativaD;

        private Label labelAlternativaA;
        private Label labelAlternativaB;
        private Label labelAlternativaC;
        private Label labelAlternativaD;

        public int TempoRestante
        {
            get { return tempoRestante; }
            set { tempoRestante = value; }
        }

        protected new TelaDeJogarQA telaPai;

        public QuizForm(Vector2 posicaoJanelaQuiz, Vector2 tamanhoJanelaQuiz, TelaDeJogarQA telaPai)
            : base(
            posicaoJanelaQuiz, tamanhoJanelaQuiz, TITULO,
                Color.DarkBlue, Color.White, ConteinerAuxiliar.fontePadrao,
                1f, true, false, true, false, Form.BorderStyle.FixedSingle,
                Form.Style.Default, null)
        {
            alturaTexto = font.MeasureString("A").Y + 6;

            labelTempoRestante = new Label("LabelTempoRestante", new Vector2(10, 35), "Tempo restante:", Label.Alignment.Center, null, Color.White, font);
            Add(labelTempoRestante);

            labelEnunciado = new Label("LabelEnunciado", new Vector2(10, 75), "Enunciado:", Label.Alignment.Center, null, Color.White, font);
            Add(labelEnunciado);

            botaoAlternativaA = new TextButton("botaoAlternativaA", new Vector2(10, posicaoAlternativas), "A", null, Color.White, font, Style.Default);
            botaoAlternativaA.OnPress += new EventHandler(ClickAlternativaA);
            Add(botaoAlternativaA);
            labelAlternativaA = new Label("labelAlternativaA", new Vector2(50, posicaoAlternativas), "A", Label.Alignment.Center, null, Color.White, font);
            Add(labelAlternativaA);

            botaoAlternativaB = new TextButton("botaoAlternativaB", new Vector2(10, posicaoAlternativas + alturaTexto), "B", null, Color.White, font, Style.Default);
            botaoAlternativaB.OnPress += new EventHandler(ClickAlternativaB);
            Add(botaoAlternativaB);
            labelAlternativaB = new Label("labelAlternativaB", new Vector2(50, posicaoAlternativas + alturaTexto), "B", Label.Alignment.Center, null, Color.White, font);
            Add(labelAlternativaB);

            botaoAlternativaC = new TextButton("botaoAlternativaC", new Vector2(10, posicaoAlternativas + alturaTexto * 2), "C", null, Color.White, font, Style.Default);
            botaoAlternativaC.OnPress += new EventHandler(ClickAlternativaC);
            Add(botaoAlternativaC);
            labelAlternativaC = new Label("labelAlternativaC", new Vector2(50, posicaoAlternativas + alturaTexto * 2), "C", Label.Alignment.Center, null, Color.White, font);
            Add(labelAlternativaC);

            botaoAlternativaD = new TextButton("botaoAlternativaD", new Vector2(10, posicaoAlternativas + alturaTexto * 3), "D", null, Color.White, font, Style.Default);
            botaoAlternativaD.OnPress += new EventHandler(ClickAlternativaD);
            Add(botaoAlternativaD);
            labelAlternativaD = new Label("labelAlternativaD", new Vector2(50, posicaoAlternativas + alturaTexto * 3), "D", Label.Alignment.Center, null, Color.White, font);
            Add(labelAlternativaD);
        
            cronometro = new Timer(1000);
            cronometro.AutoReset = true;
            cronometro.Elapsed += new ElapsedEventHandler(AtualizarCronometro);
                        
            this.telaPai = telaPai;
        }

        void ClickAlternativaA(object sender, EventArgs e)
        {
            Responder(labelAlternativaA.Text);
        }

        void ClickAlternativaB(object sender, EventArgs e)
        {
            Responder(labelAlternativaB.Text);
        }

        void ClickAlternativaC(object sender, EventArgs e)
        {
            Responder(labelAlternativaC.Text);
        }

        void ClickAlternativaD(object sender, EventArgs e)
        {
            Responder(labelAlternativaD.Text);
        }

        void Responder(String textoAlternativaEscolhida)
        {
            if (textoAlternativaEscolhida.Equals(textoAlternativaCerta))
            {
                telaPai.Pontuacao += ConstantesQA.PONTUACAO_POR_ACERTAR_PERGUNTA;
            }
            else
            {
                telaPai.Pontuacao += ConstantesQA.PONTUACAO_POR_ERRAR_PERGUNTA;
            }

            FecharJanela();
        }

        public override void Update()
        {
            labelTempoRestante.Text = TEMPO_RESTANTE + TempoRestante + "s";

            if (windowState == WindowState.Minimized ||
                windowState == WindowState.Minimizing)
            {
                title = TempoRestante + "s";
            }
            else
            {
                title = TITULO;
            }

            base.Update();
        }

        void AtualizarCronometro(object sender, ElapsedEventArgs e)
        {
            if (TempoRestante > 0)
            {
                TempoRestante -= 1;
            }
            else
            {
                if (cronometroFuncionando)
                {
                    telaPai.Pontuacao += ConstantesQA.PONTUACAO_POR_ACABAR_O_TEMPO;
                    FecharJanela();
                }
            }
        }

        public void FecharJanela()
        {
            Hide();
            cronometroFuncionando = false;

            telaPai.SolicitouPergunta = false;
        }

        public void ReiniciarCronometro()
        {
            TempoRestante = ConstantesQA.TEMPO_PARA_RESPONDER;

            cronometro.Start();

            cronometroFuncionando = true;
        }

        public void ExibirPergunta(Pergunta pergunta)
        {
            if (!bVisible)
            {
                String enunciado = pergunta.Enunciado;

                textoAlternativaCerta = pergunta.AlternativaCerta;

                labelEnunciado.Text = QuebrarPalavra(enunciado);

                List<String> alternativas = new List<String>();
                alternativas.Add(textoAlternativaCerta);

                foreach (String alternativaErrada in pergunta.AlternativasErradas)
                {
                    alternativas.Add(alternativaErrada);
                }

                size.Y = posicaoAlternativas + alturaTexto * (alternativas.Count + 1);

                PrencherAlternativa(alternativas, botaoAlternativaA, labelAlternativaA, 0);
                PrencherAlternativa(alternativas, botaoAlternativaB, labelAlternativaB, 1);
                PrencherAlternativa(alternativas, botaoAlternativaC, labelAlternativaC, 2);
                PrencherAlternativa(alternativas, botaoAlternativaD, labelAlternativaD, 3);
                
                ReiniciarCronometro();

                Show();
                SetFocus();
            }
        }

        public void PrencherAlternativa(List<String> alternativas, TextButton botao, Label label, int indice)
        {
            if (alternativas.Count != 0)
            {
                botao.origin.Y = posicaoAlternativas + alturaTexto * indice;
                label.origin.Y = posicaoAlternativas + alturaTexto * indice;
                label.Text = SortearAlternativa(alternativas);
            }
            else
            {
                botao.origin.Y = float.MaxValue;
                label.origin.Y = float.MaxValue;
            }
        }

        public String SortearAlternativa(List<String> alternativas)
        {
            int indiceSorteado = random.Next(alternativas.Count);
            String alternativaSorteada = alternativas[indiceSorteado];
            alternativas.Remove(alternativaSorteada);

            return alternativaSorteada;
        }

        public String QuebrarPalavra(String palavra)
        {
            Vector2 tamanhoPalavra = font.MeasureString(palavra);

            int linhasNecessarias = (int)(tamanhoPalavra.X / size.X);

            int letrasNaParte = 1;

            String palavraQuebrada = "";
            String parteDaPalavra = "";

            posicaoAlternativas = 100;

            for (int iInicial = 0; iInicial + letrasNaParte <= palavra.Length; letrasNaParte++)
            {
                parteDaPalavra = palavra.Substring(iInicial, letrasNaParte);
                Vector2 tamanhoDaParte = font.MeasureString(parteDaPalavra);

                if (tamanhoDaParte.X >= size.X - 22)
                {
                    iInicial += letrasNaParte;

                    if (!parteDaPalavra.EndsWith(" "))
                    {
                        int ultimoEspaco = parteDaPalavra.LastIndexOf(" ");
                        int indicesAVoltar = parteDaPalavra.Length - 1 - ultimoEspaco;

                        palavraQuebrada += parteDaPalavra.Substring(0, ultimoEspaco);
                        iInicial -= indicesAVoltar;
                    }
                    else
                    {
                        palavraQuebrada += parteDaPalavra;
                    }

                    letrasNaParte = 1;
                    posicaoAlternativas += tamanhoDaParte.Y;

                    if (iInicial < palavra.Length - 1)
                    {
                        palavraQuebrada += "\n";
                    }

                }
            }

            palavraQuebrada += parteDaPalavra;

            return palavraQuebrada;
        }

        protected override void closeButton_onMouseRelease(Object obj, EventArgs e)
        {
            if (Form.topForm != this)
                return;

            telaPai.Pontuacao += ConstantesQA.PONTUACAO_POR_FECHAR_PERGUNTA;
            
            Hide();
        }
    }
}
